
from OpenGL.raw.GL.constants import GL_MODELVIEW
from OpenGL.raw.GL.constants import GL_PROJECTION
from game.gameobjects.matrix44 import *
from game.gameobjects.vector3 import *
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
from math import radians
from game.object.world.world import *

#an entity is a thing that exists in the world and moves about, like the player character
#Entities are relative to the 10m level of inception
class Entity:
    def __init__(self):
        self.matrix = Matrix44()
        self.cell = None
        
        #temporary
        self.cpos = None

        self.rotation_speed = radians(90.0)
        self.movement_speed = 0.05
        self.mouse_sensitivity = 100.0

        self.rotation_vector = Vector3()
        self.movement_vector = Vector3()

        self.rotation_current = Vector3()
        self.movement_current = Vector3()

        self.rotation_min = Vector3(radians(-80.0), 0, 0)
        self.rotation_max = Vector3(radians(80.0), 0, 0)

        self.key_def = {
            K_LEFT: (self.rotation_vector, 1, 1),
            K_RIGHT: (self.rotation_vector, 1, -1),
            K_UP: (self.rotation_vector, 0, 1),
            K_DOWN: (self.rotation_vector, 0, -1),
            K_q: (self.rotation_vector, 2, 1),
            K_e: (self.rotation_vector, 2, -1),
            K_w: (self.movement_vector, 2, -1),
            K_s: (self.movement_vector, 2, 1),
            K_a: (self.movement_vector, 0, -1),
            K_d: (self.movement_vector, 0, 1),
        }

        self.scale = 10

    def place_in_cell(self, cell):

        self.cell = cell
        cell.entities.append(self)
        self.scale = 10000
        for i in xrange(self.cell.depth):
            self.scale *= .1

#    def to_real_coord(self, root_coord):
#        rel_coord = self.cell[-3] - root_coord[0] + self.movement_current[0], \
#            self.cell[-2] - root_coord[1] + self.movement_current[1], \
#            self.cell[-1] - root_coord[2] + self.movement_current[2]
#
#        real_coord = [rel_coord[i] * self.scale for i in rel_coord]
#        return real_coord


    def event(self, evt, ms):
        if evt.type == KEYDOWN:
            if evt.key in self.key_def:
                a, k, v = self.key_def[evt.key]
                a[k] += v
        if evt.type == KEYUP:
            if evt.key in self.key_def:
                a, k, v = self.key_def[evt.key]
                a[k] -= v

    def update(self, ms):
        ms_sec = ms / 1000.

        # Reset rotation and movement directions


        # Calculate rotation matrix and multiply by camera matrix
        if self.rotation_vector != Vector3():
            self.handle_rotation(ms_sec)

        # Calculate movement and add it to camera matrix translate
        if self.movement_vector != Vector3():
            self.handle_movement(ms_sec)


        self.matrix = Matrix44()
        self.matrix.translate = self.movement_current
        self.matrix *= Matrix44.y_rotation(self.rotation_current.y)
        self.matrix *= Matrix44.x_rotation(self.rotation_current.x)


    def handle_rotation(self, ms):
        rotation = self.rotation_vector * self.rotation_speed * ms
        self.rotation_current += rotation

    def handle_movement(self, ms):
        heading = Vector3(self.matrix.forward)
        strafe = Vector3(self.matrix.right)
        movement = (heading * self.movement_vector.z * self.movement_speed) + \
            (strafe * self.movement_vector.x * self.movement_speed)
        self.movement_current += (movement * ms)

        while self.movement_current.x < 0:
            self.movement_current.x += 1
            #self.cpos[0] -= 1
            #self.cell = self.cell.get_neighbour(WORLD_XN)
        while self.movement_current.x >= 1:
            self.movement_current.x -= 1
            #self.cpos[0] += 1
            #self.cell = self.cell.get_neighbour(WORLD_XP)
        while self.movement_current.y < 0:
            self.movement_current.y += 1
            #self.cpos[1] -= 1
            #self.cell = self.cell.get_neighbour(WORLD_YN)
        while self.movement_current.y >= 1:
            self.movement_current.y -= 1
            #self.cpos[1] += 1
            #self.cell = self.cell.get_neighbour(WORLD_YP)
        while self.movement_current.z < 0:
            self.movement_current.z += 1
            #self.cpos[2] -= 1
            #self.cell = self.cell.get_neighbour(WORLD_ZN)
        while self.movement_current.z >= 1:
            self.movement_current.z -= 1
            #self.cpos[2] += 1
            #self.cell = self.cell.get_neighbour(WORLD_ZP)


    def draw(self):

        #glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        
#        mat = glGetDoublev(GL_MODELVIEW_MATRIX)
#        for i in xrange(3):
#            for j in xrange(3):
#                if i == j:
#                    mat[i][j] = 0.1#self.scale
#                else:
#                    mat[i][j] = 0
#        glLoadMatrixf(mat)

        #modelMatrix = glGetDoublev(GL_MODELVIEW_MATRIX)

        #print modelMatrix
        #glLoadIdentity()
        #glScaled(20, 10, 30)
        #modelMatrix = glGetDoublev(GL_MODELVIEW_MATRIX)
        #print "afta\n", modelMatrix
        #glScaled(self.scale, self.scale, self.scale)
#        glTranslate(self.cell.x + self.movement_current[0],
#            self.cell.y + self.movement_current[1],
#            self.cell.z + self.movement_current[2])

#        glTranslate(self.cpos[0] + self.movement_current[0],
#            self.cpos[1] + self.movement_current[1],
#            self.cpos[2] + self.movement_current[2])

#        print (self.cpos[0], self.movement_current[0],
#            self.cpos[1], self.movement_current[1],
#            self.cpos[2], self.movement_current[2])

        glBegin(GL_LINES)
        glColor4f(0,0,255,255)

        glVertex3f(0,0,0)
        glVertex3f(0,100,0)

        glEnd()
        glPopMatrix()

        #print 'tray'
